package com.eks.shiro.exceptions;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

/**
 * GlobalExceptionHandler
 *
 * @author: chenfenghai
 * @version: 1.0
 * @date: 2021-02-04 16:15
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handleValidationException(ConstraintViolationException e){
        for(ConstraintViolation<?> s:e.getConstraintViolations()){
            return s.getInvalidValue()+": "+s.getMessage();
        }
        return "请求参数不合法";
    }

    //不满足@RequiresGuest注解时抛出的异常信息
    private static final String GUEST_ONLY = "Attempting to perform a guest-only operation";


    @ExceptionHandler(ShiroException.class)
    @ResponseBody
    public String handleShiroException(ShiroException e) {
        log.error("shiro执行出错", e);
        return "鉴权或授权过程出错";
    }

    @ExceptionHandler(UnauthenticatedException.class)
    @ResponseBody
    public String page401(UnauthenticatedException e) {
        log.error("UnauthenticatedException");
        String eMsg = e.getMessage();
        if (StringUtils.startsWithIgnoreCase(eMsg,GUEST_ONLY)){
            return "只允许游客访问，若您已登录，请先退出登录";
        }else{
            return "用户未登录";
        }
    }

    @ExceptionHandler(UnauthorizedException.class)
    @ResponseBody
    public String page403() {
        log.error("用户没有访问权限");
        return "用户没有访问权限";
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String exception(Exception ex) {
        log.error("未处理异常:", ex);
        return "未处理异常";
    }
}
